/* eslint-disablet */
import { BaseSlateItemType, DocItem, DocItemType, ShareDocEditorData, SlateDescendant } from '../types';

import { isHeading } from '.';

/**
 * 解析数据至组件暴露API的数据格式
 * @param items
 * @param data
 * @param originDocItems
 * @returns
 */
export const parseToDocData = (items: SlateDescendant[], data: ShareDocEditorData, originDocItems: DocItem[]) => {
  let textStyleIndex = 0;
  const textStyleMapItems: { [index: DocItem['id']]: DocItem['textStyleMap'] } = {};
  const originDocItemsMap = originDocItems.reduce(
    (r, c) => {
      r[c.id] = c;
      return r;
    },
    {} as { [id: string | number]: DocItem },
  );
  const dataGroup = Object.keys(data)
    .map((key) => key.split('/'))
    .reduce(
      (r, [id, text]) => {
        const groupData = r[id] || {};
        groupData[text || ''] = `${data[`${id}/${text}`] || ''}`;
        r[id] = groupData;
        return r;
      },
      {} as { [id: string]: { [text: string]: string | number } },
    );
  const joinText = (item: SlateDescendant, id: number | string = 'invalid') => {
    if ('text' in item) {
      if (Object.keys(item).length > 1) {
        const indexMark = `$$[${textStyleIndex}]`;
        const styleMap = textStyleMapItems[id] || {};
        // @ts-ignore
        styleMap[indexMark] = item;
        textStyleIndex += 1;
        textStyleMapItems[id] = styleMap;
        return indexMark;
      }
      return item.text || '';
    }
    switch (item.type) {
      case BaseSlateItemType.Input:
      case BaseSlateItemType.Tag: {
        const leaf = item.children[0] || {};
        if (Object.keys(leaf).length > 1) {
          const indexMark = `$$[${textStyleIndex}]`;
          const styleMap = textStyleMapItems[id] || {};
          // @ts-ignore
          styleMap[indexMark] = { ...leaf, text: item.mark || '' };
          textStyleIndex += 1;
          textStyleMapItems[id] = styleMap;
          if (item.scene === 'index') {
            styleMap.index = styleMap[indexMark];
            return '';
          }
          return indexMark;
        }
        return item.mark || '';
      }
      default:
        return item.children.reduce((r, c: SlateDescendant): string => `${r}${joinText(c, id)}`, '');
    }
  };

  const docItems = items
    .map((item) => {
      if ('text' in item) return null;
      const { id, type } = item;
      const text = joinText(item, id);
      let d = dataGroup[id ?? ''] || null;
      switch (type) {
        case DocItemType.H1:
        case DocItemType.H2:
        case DocItemType.H3:
        case DocItemType.H4:
        case DocItemType.H5:
        case DocItemType.H6:
          d = d || {};
          d['$[INDEX]'] = data[`${id}/$[INDEX]`];
          break;
      }
      return {
        ...originDocItemsMap[id || ''],
        id,
        type,
        text,
        data: d,
        //@ts-ignore
        externalData: item.externalData,
        textStyleMap: textStyleMapItems[id ?? ''],
        style: {
          //@ts-ignore
          align: item.align,
        },
      };
    })
    .filter(Boolean) as DocItem[];
  // console.log("docItems--->111", docItems)
  const docItemsMap = docItems.reduce(
    (r, c) => {
      const text = r[c.id]?.text;
      const styleMap = c.textStyleMap;
     
      c.text = `${typeof text === 'string' ? `${text}\n` : ''}${c.text || ''}`;
      c.plainText =
        `${isHeading(c.type) ? `${c.data?.['$[INDEX]'] || ''} ` : ''}` +
        c.text
          .replace(/\$\$\[\d+]/g, (s) => styleMap?.[s].text ?? s)
          // .replace(/\$?\[[SXNU]]/g, (s) => `${c.data?.[s] ?? s}`)
          .replace(/\$?\[[SXNU].*?]/g, (s) => `${c.data?.[s] ?? s}`)
          .replace(/\$?\[(\*|(NAME)|P|(type))]/g, (s) => `${data[s] ?? s}`);
      r[c.id] = c;
      // console.log("r---->", r, c)
      return r;
    },
    {} as { [id: string | number]: DocItem },
  );
  return Array.from(new Set(docItems.map(({ id }) => id)))
    .filter(Boolean)
    .map((id) => docItemsMap[id]);
};
